package com.wkq.net.down

import android.annotation.SuppressLint
import android.app.ActivityManager
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.ServiceConnection
import android.os.IBinder
import android.os.RemoteException
import com.wkq.net.IDownloadCallback
import com.wkq.net.IDownloadService
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.cancel
import kotlinx.coroutines.launch
import java.io.File
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.ConcurrentLinkedQueue
import java.util.Locale

class DownloadManager private constructor(private val context: Context) {

    companion object {
        @SuppressLint("StaticFieldLeak")
        @Volatile
        private var instance: DownloadManager? = null

        fun getInstance(context: Context): DownloadManager {
            if (instance == null) {
                synchronized(DownloadManager::class.java) {
                    if (instance == null) {
                        instance = DownloadManager(context)
                    }
                }
            }
            return instance!!
        }
    }

    private val ioScope = CoroutineScope(Dispatchers.Main + SupervisorJob())
    private var downloadService: IDownloadService? = null
    private var isBound = false
    private val downloadListeners = ConcurrentHashMap<String, DownloadListener>()
    private val pendingDownloads = ConcurrentLinkedQueue<PendingDownload>()

    // 下载回调
    private val callback = object : IDownloadCallback.Stub() {
        override fun onProgressChanged(url: String, type: String, progress: Int) {
            ioScope.launch {
                downloadListeners[url]?.onProgress(url, type, progress)
            }
        }

        override fun onDownloadComplete(url: String, type: String, filePath: String) {
            ioScope.launch {
                downloadListeners[url]?.onComplete(url, type, filePath)
                downloadListeners.remove(url)
            }
        }

        override fun onDownloadFailed(url: String, type: String, errorMsg: String) {
            ioScope.launch {
                downloadListeners[url]?.onFailed(url, type, errorMsg)
                downloadListeners.remove(url)
            }
        }
    }

    // 服务连接
    private val serviceConnection = object : ServiceConnection {
        override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
            downloadService = IDownloadService.Stub.asInterface(service)
            isBound = true
            try {
                downloadService?.registerCallback(callback)
            } catch (e: RemoteException) {
                e.printStackTrace()
            }
            processPendingDownloads()
        }

        override fun onServiceDisconnected(name: ComponentName?) {
            isBound = false
            downloadService = null
        }
    }

    fun bindService() {
        if (!isBound) {
            val intent = Intent(context, DownloadService::class.java)
            context.bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE)
        }
    }

    private fun unbindService() {
        if (isBound) {
            try {
                downloadService?.unregisterCallback(callback)
            } catch (e: RemoteException) {
                e.printStackTrace()
            }
            context.unbindService(serviceConnection)
            isBound = false
        }
    }

    // 检查服务是否正在运行（仅检查自己绑定状态）
    private fun isServiceRunning(): Boolean = isBound

    fun downloadFile(url: String, type: String, fileDir: String, listener: DownloadListener) {
        bindService()
        downloadListeners[url] = listener
        val dir = File(fileDir)
        if (!dir.exists()) dir.mkdirs()

        if (downloadService != null) {
            try {
                downloadService?.downloadFile(url, type, fileDir)
            } catch (e: RemoteException) {
                listener.onFailed(url, type, "Service communication error: ${e.message}")
            }
        } else {
            pendingDownloads.add(PendingDownload(url, type, fileDir, listener))
        }
    }

    private fun processPendingDownloads() {
        var pending = pendingDownloads.poll()
        while (pending != null) {
            try {
                downloadService?.downloadFile(pending.url, pending.type, pending.fileDir)
            } catch (e: RemoteException) {
                pending.listener.onFailed(
                    pending.url,
                    pending.type,
                    "Service communication error: ${e.message}"
                )
            }
            pending = pendingDownloads.poll()
        }
    }

    fun cancelDownload(url: String, type: String) {
        try {
            downloadService?.cancelDownload(url, type)
            downloadListeners.remove(url)
        } catch (e: RemoteException) {
            e.printStackTrace()
        }
    }

    fun release() {
        unbindService()
        downloadListeners.clear()
        pendingDownloads.clear()
        ioScope.cancel()
        instance = null
    }

    interface DownloadListener {
        fun onProgress(url: String, type: String, progress: Int)
        fun onComplete(url: String, type: String, filePath: String)
        fun onFailed(url: String, type: String, errorMsg: String)
    }

    private data class PendingDownload(
        val url: String,
        val type: String,
        val fileDir: String,
        val listener: DownloadListener
    )
}
